from flask import Flask, request, jsonify
import os
import shutil
from pathlib import Path
import edge_tts
import asyncio
from werkzeug.utils import secure_filename
from datetime import datetime
import logging
import uuid  # 添加在文件顶部的导入部分
print(os.getenv('FLASK_ENV'))  # 应该输出 'development'

class Config:
    """配置类"""
    DEBUG = os.getenv('FLASK_ENV') == 'development'
    BASE_URL = 'http://127.0.0.1:5000' if DEBUG else 'https://laobaoai.com:446'
    SERVER = 'flask' if DEBUG else 'waitress'

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/audio'
app.config['BASE_URL'] = Config.BASE_URL

# 禁用Flask默认的访问日志
import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.WARNING)

class TextToSpeechAPI:
    """API版本的文本转语音服务"""
    
    def __init__(self):
        self.cache_dir = Path("tts_cache")
        self.cache_dir.mkdir(exist_ok=True)
        
        self.voice_profiles = {
            'female': 'zh-CN-XiaoxiaoNeural',
            'male': 'zh-CN-YunyangNeural',
            'child': 'zh-CN-XiaoyiNeural',
            'elderly': 'zh-CN-YunyeNeural'
        }
        
        # 确保音频输出目录存在
        os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
    
    def _get_cache_file(self, api_token, text, voice_type):
        # 使用内容哈希作为文件名基础
        content_hash = hash(f"{api_token}_{text}_{voice_type}")
        return self.cache_dir / f"{content_hash}.mp3"

    async def _async_convert(self, text, output_path, voice_type, rate="+0%"):
        """异步执行TTS转换"""
        voice = self.voice_profiles.get(voice_type, 'zh-CN-XiaoxiaoNeural')
        communicate = edge_tts.Communicate(text=text, voice=voice, rate=rate)
        await communicate.save(output_path)

    def convert(self, api_token, text, voice_type='female', rate="+0%"):
        """转换文本为语音并返回URL"""
        try:
            # 生成基于内容哈希的文件名
            content_hash = hash(f"{api_token}_{text}_{voice_type}")
            filename = f"{content_hash}.mp3"
            output_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            
            # 检查缓存
            cache_file = self._get_cache_file(api_token,text, voice_type)
            if cache_file.exists():
                shutil.copy(cache_file, output_path)
                return f"{app.config['BASE_URL']}/{output_path}"
                
            # 合成语音
            # 修改事件循环处理方式
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            loop.run_until_complete(
                self._async_convert(text, output_path, voice_type, rate))
            
            # 保存到缓存
            shutil.copy(output_path, cache_file)
            return f"{app.config['BASE_URL']}/{output_path}"
            
        except Exception as e:
            print(f"Error in TTS conversion: {e}")
            return None

tts_api = TextToSpeechAPI()

# 配置日志系统
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(message)s',
    handlers=[
        logging.FileHandler('tts_api.log'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

@app.route('/api/tts/text_to_audio', methods=['POST'])
def text_to_speech():
    """处理TTS请求的API端点"""
    start_time = datetime.now()  # 现在这行应该可以正常工作了
    data = request.json
    
    try:
        # 记录请求信息
        log_data = {
            'client_ip': request.remote_addr,
            'user_agent': request.headers.get('User-Agent', 'Unknown'),
            'method': request.method,
            'path': request.path,
            'request': data,
            'status': None,
            'response': None,
            'duration': None
        }
        
        api_token = data.get('api_token', '')
        text = data.get('text', '')
        voice_type = data.get('voice_type', 'female')
        rate = data.get('rate', '+0%')
        
        if not text:
            response = jsonify({
                'status': 'error',
                'code': 400,
                'message': 'Text parameter is required',
                'data': None
            })
            log_data.update({
                'status': 400,
                'response': {'error': 'Text parameter is required'},
                'duration': (datetime.now() - start_time).total_seconds()
            })
            logger.info(f"API请求记录: {log_data}")
            return response, 400
        
        audio_url = tts_api.convert(api_token,text, voice_type, rate)
        
        if audio_url:
            response_data = {
                'status': 'success',
                'url': audio_url
            }
            response = jsonify({
                'status': 'success',
                'code': 200,
                'message': 'Audio generated successfully',
                'data': {'url': audio_url,'api_token':api_token}
            })
            log_data.update({
                'status': 200,
                'response': response_data,
                'duration': (datetime.now() - start_time).total_seconds()
            })
            logger.info(f"API请求记录: {log_data}")
            return response
        else:
            response = jsonify({
                'status': 'error',
                'code': 500,
                'message': 'Failed to generate audio',
                'data': None
            })
            log_data.update({
                'status': 500,
                'response': {'error': 'Failed to generate audio'},
                'duration': (datetime.now() - start_time).total_seconds()
            })
            logger.info(f"API请求记录: {log_data}")
            return response, 500
            
    except Exception as e:
        log_data.update({
            'status': 500,
            'response': {'error': str(e)},
            'duration': (datetime.now() - start_time).total_seconds()
        })
        logger.error(f"API请求记录: {log_data}")
        return jsonify({
            'status': 'error',
            'code': 500,
            'message': 'Internal server error',
            'data': None
        }), 500

# 修改Flask启动配置
if __name__ == '__main__':
    # 设置Windows下的事件循环策略
    if os.name == 'nt':
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    
    if Config.SERVER == 'flask':
        app.run(host='0.0.0.0', port=5000, debug=Config.DEBUG)
    else:
        from waitress import serve
        serve(app, host='0.0.0.0', port=5000)
